home *** CD-ROM | disk | FTP | other *** search
- From: Torsten Scherer <itschere@techfak.uni-bielefeld.de>
- Subject: MiNT 1.09 diffs: XATTR for biosfs & more
- Date: Sun, 28 Nov 93 14:59:22 +0100
-
- Hi there!
-
- Here's finally the result of all my questions and/or discussions about the
- bios filesystem and the XATTR structure. I consider them being serious ideas
- and would like to have them officially included, that's why I tried to be so
- carefully and wanted to discuss this first.
-
- It's true that the datime() method would provide more security if you
- couldn't directly access the bios_file structure via f->fc.index, but
- removing this would cause a major rewrite of the biosfs code and might
- end up in using a size-fixed list of bios_file's for which the fc.index
- field isn't really more than an index, plus some more troubles like what
- happens if you install an extra bios device but the internal datime() call
- doesn't know about this bios number. Ah, well, plus some more, perhaps.
-
- So I choose the other way round that every external device driver can
- access this structure as described above and is fully responsible for time
- updates or any other trash it might perhaps want to do. To minimize the
- risk a bit, Dcntl() calls are now restricted to the superuser.
-
- This shouldn't disturb you if you're using MiNT as a basis for MultiTOS,
- since you'll never be anybody else but the superuser, but will hopefully
- conform the ideas of most of the people using it for other purposes, like
- a UN*X like system.
-
- Since this also involves changes in the fasttext driver, I've chosen to put
- the declaration of the bios_file into file.h, so that it can be easily
- accessed by it or any other future device drivers.
-
- There are actually some more security changes, so here comes a brief list:
-
- file.h, biosfs.c, fasttext.c:
- - added XATTR structure to bios files allowing them to have ownership, access
- modes and timestamps like any(?) other file
- - restricted Dcntl() calls to the superuser to be a bit more secure
- - fixed a bug with links so that ls now works correct on them
-
- mint.h, syscall.spp, bios.c:
- - introduced a flag variable "in_dos", which allows bios calls to determine
- if they derived from a gemdos call or not. most important application:
- rwabs() is now only allowed if you're either the superuser or it was
- a gemdos call, thus making it impossible(?) for any other user to
- trash the filesystem
-
- tosfs.c:
- - changed the getxattr() call so that the "other user" bits are masked out, so
- files will look like "rwxrwx---" and again only the superuser is
- allowed to access TOS partitions. Is there a better way of protection?
- - changed the chown() call to report the change was successfully, cause I
- was getting really annoyed by mv's error messages
-
- so long,
- TeSche
- --
- PS: If the above written looks weird, then that's probably because it _is_.
- WhoDunnIt: Torsten Scherer (Schiller, Tesche, ...)
- Where: Faculty of Technology, University of Bielefeld, Germany
- EMail: itschere@techfak.uni-bielefeld.de / tesche@hrz.uni-bielefeld.de
-
- --- cut cut cut ---
- diff -u4 orig/bios.c my/bios.c
- --- orig/bios.c Fri Nov 19 15:33:56 1993
- +++ my/bios.c Fri Nov 19 17:37:58 1993
- @@ -80,8 +80,11 @@
- /* variables for monitoring the keyboard */
- IOREC_T *keyrec; /* keyboard i/o record pointer */
- short kintr = 0; /* keyboard interrupt pending (see intr.s) */
-
- +/* TeSche: flag to recognize GEMDOS operations */
- +int in_dos;
- +
- /* Getmpb is not allowed under MiNT */
-
- long ARGS_ON_STACK
- getmpb(ptr)
- @@ -305,8 +308,14 @@
- long lrecno;
- {
- long r;
- extern PROC *dlockproc[]; /* in dosdir.c */
- +
- + /* TeSche: */
- + if (curproc->euid && !in_dos) {
- + DEBUG(("Rwabs by non-privileged process requested"));
- + return EACCDN;
- + }
-
- if (dev >= 0 && dev < NUM_DRIVES && dlockproc[dev]) {
- if (dlockproc[dev] != curproc) {
- DEBUG(("Rwabs: device %c is locked", dev+'A'));
- diff -u4 orig/biosfs.c my/biosfs.c
- --- orig/biosfs.c Fri Nov 19 15:34:00 1993
- +++ my/biosfs.c Mon Nov 29 09:13:20 1993
- @@ -108,20 +108,8 @@
-
- struct tty con_tty, aux_tty, midi_tty;
- struct tty sccb_tty, scca_tty, ttmfp_tty;
-
- -#define BNAME_MAX 13
- -
- -struct bios_file {
- - char name[BNAME_MAX+1]; /* device name */
- - DEVDRV *device; /* device driver for device */
- - short private; /* extra info for device driver */
- - ushort flags; /* flags for device open */
- - struct tty *tty; /* tty structure (if appropriate) */
- - struct bios_file *next;
- - short lockpid; /* owner of the lock */
- -};
- -
- struct bios_file BDEV[] = {
-
- /* "real" bios devices present on all machines */
- {"centr", &bios_ndevice, 0, 0, 0, 0},
- @@ -166,16 +154,54 @@
- */
-
- FILEPTR *defaultaux;
-
- +/* ts: a xattr field used for the root directory, 'cause there's no
- + * bios_file structure for it.
- + */
- +
- +XATTR rxattr;
- +
- +/* ts: a small utility function to set up a xattr structure
- + */
- +
- +void set_xattr(XATTR *xp, ushort mode)
- +{
- + xp->mode = mode;
- + xp->index = 0L;
- + xp->dev = 0;
- + xp->reserved1 = 0L;
- + xp->nlink = 1;
- + xp->uid = curproc->euid;
- + xp->gid = curproc->egid;
- + xp->size = 0L;
- + xp->blksize = 1L;
- + xp->nblocks = 0L;
- +/* timestamp/datestamp are not yet initialized when the biosfs comes up */
- + xp->mtime = xp->atime = xp->ctime = Tgettime();
- + xp->mdate = xp->adate = xp->cdate = Tgetdate();
- +/* root directory only */
- + if ((mode & S_IFMT) == S_IFDIR)
- + xp->attr = FA_DIR;
- + else
- + xp->attr = 0;
- + xp->reserved2 = 0;
- + xp->reserved3[0] = 0L;
- + xp->reserved3[1] = 0L;
- +}
- +
- void
- biosfs_init()
- {
- struct bios_file *b;
-
- broot = BDEV;
- + set_xattr(&rxattr, S_IFDIR | DEFAULT_DIRMODE);
-
- for (b = broot; b->name[0]; b++) {
- +
- + set_xattr(&b->xattr, S_IFCHR | DEFAULT_MODE);
- +
- b->next = b+1;
-
- /* if not a TT or Mega STE, adjust the MODEM1 device to be BIOS
- * device 1
- @@ -270,32 +296,25 @@
- {
- FILEPTR *f;
- struct bios_file *b = (struct bios_file *)fc->index;
-
- - xattr->index = fc->index;
- - xattr->dev = fc->dev;
- - xattr->nlink = 1;
- - xattr->uid = xattr->gid = 0;
- - xattr->size = xattr->nblocks = 0;
- - xattr->blksize = 1;
- - xattr->mtime = xattr->atime = xattr->ctime = timestamp;
- - xattr->mdate = xattr->adate = xattr->cdate = datestamp;
- - if (fc->index == 0) { /* root directory? */
- - xattr->mode = S_IFDIR | DEFAULT_DIRMODE;
- - xattr->attr = FA_DIR;
- - } else if (b->device == 0) { /* symbolic link? */
- - xattr->mode = S_IFLNK | DEFAULT_DIRMODE;
- - } else if (b->device == &fakedev &&
- - (f = curproc->handle[b->private]) != 0)
- - {
- - /* u:\dev\stdin, u:\dev\stdout, etc. */
- - (*f->fc.fs->getxattr) (&f->fc, xattr);
- - xattr->index = fc->index;
- - xattr->dev = fc->dev;
- + if (b == 0) {
- + /* root directory */
- + *xattr = rxattr;
- + xattr->index = fc->index;
- + xattr->dev = fc->dev;
- + } else if (b->device == &fakedev && (f = curproc->handle[b->private]) != 0) {
- + /* u:\dev\stdin, u:\dev\stdout, etc. */
- + (*f->fc.fs->getxattr) (&f->fc, xattr);
- + xattr->index = fc->index;
- + xattr->dev = fc->dev;
- } else {
- - xattr->mode = S_IFCHR | DEFAULT_MODE;
- - xattr->attr = 0;
- + /* all the rest... */
- + *xattr = b->xattr;
- + xattr->index = fc->index;
- + xattr->dev = fc->dev;
- }
- +
- return 0;
- }
-
- static long ARGS_ON_STACK
- @@ -311,20 +330,48 @@
- bios_chown(fc, uid, gid)
- fcookie *fc;
- int uid, gid;
- {
- - UNUSED(fc); UNUSED(uid);
- - UNUSED(gid);
- - return EINVFN;
- + struct bios_file *b = (struct bios_file *)fc->index;
- +
- + if (!(curproc->euid)) {
- + if (!b) {
- + /* biosfs root directory */
- + rxattr.uid = uid;
- + rxattr.gid = gid;
- + } else {
- + /* any other entry */
- + b->xattr.uid = uid;
- + b->xattr.gid = gid;
- + }
- +
- + return 0;
- + }
- +
- + return EACCDN;
- }
-
- static long ARGS_ON_STACK
- bios_chmode(fc, mode)
- fcookie *fc;
- unsigned mode;
- {
- - UNUSED(fc); UNUSED(mode);
- - return EINVFN;
- + struct bios_file *b = (struct bios_file *)fc->index;
- +
- + if (!b) {
- + /* root directory */
- + if (!curproc->euid || (curproc->euid == rxattr.uid)) {
- + rxattr.mode = (rxattr.mode & S_IFMT) | mode;
- + return 0;
- + }
- + } else {
- + if (!curproc->euid && (curproc->euid == b->xattr.uid)) {
- + b->xattr.mode = (b->xattr.mode & S_IFMT) | mode;
- + return 0;
- + }
- + }
- +
- + return EACCDN;
- }
-
- long ARGS_ON_STACK
- nomkdir(dir, name, mode)
- @@ -363,8 +410,13 @@
- if (!stricmp(b->name, name)) break;
- }
- if (!b) return EFILNF;
-
- +/* don't allow removal of the device if we don't own it */
- + if (curproc->euid && (curproc->euid != b->xattr.uid)) {
- + return EACCDN;
- + }
- +
- /* don't allow removal of the basic system devices */
- if (b >= BDEV && b <= bdevlast) {
- return EACCDN;
- }
- @@ -551,13 +603,24 @@
- {
- struct bios_file *b;
-
- UNUSED(dir);
- +
- + /* TeSche: */
- + if (curproc->euid) {
- + DEBUG(("biosfs: device install by non-privileged process requested"));
- + if ((unsigned)cmd) == DEV_INSTALL)
- + return 0;
- + else
- + return EACCDN;
- + }
- +
- if ((unsigned)cmd == DEV_INSTALL) {
- struct dev_descr *d = (struct dev_descr *)arg;
-
- b = kmalloc(SIZEOF(struct bios_file));
- if (!b) return 0;
- + set_xattr(&(b->xattr), S_IFCHR | DEFAULT_MODE);
- strncpy(b->name, name, BNAME_MAX);
- b->name[BNAME_MAX] = 0;
- b->device = d->driver;
- b->private = d->dinfo;
- @@ -569,8 +632,9 @@
- }
- if ((unsigned)cmd == DEV_NEWTTY) {
- b = kmalloc(SIZEOF(struct bios_file));
- if (!b) return ENSMEM;
- + set_xattr(&(b->xattr), S_IFCHR | DEFAULT_MODE);
- b->tty = kmalloc(SIZEOF(struct tty));
- if (!b->tty) {
- kfree(b);
- return ENSMEM;
- @@ -587,8 +651,9 @@
- }
- if ((unsigned)cmd == DEV_NEWBIOS) {
- b = kmalloc(SIZEOF(struct bios_file));
- if (!b) return ENSMEM;
- + set_xattr(&(b->xattr), S_IFCHR | DEFAULT_MODE);
- strncpy(b->name, name, BNAME_MAX);
- b->name[BNAME_MAX] = 0;
- b->tty = 0;
- b->device = &bios_ndevice;
- @@ -609,27 +674,38 @@
- long r;
- fcookie fc;
-
- r = bios_lookup(dir, name, &fc);
- - if (r == 0) return EACCDN; /* file already exists */
- - if (r != EFILNF) return r; /* some other error */
- + if (r == 0)
- + return EACCDN; /* file already exists */
-
- + if (r != EFILNF)
- + return r; /* some other error */
- +
- b = kmalloc(SIZEOF(struct bios_file));
- - if (!b) return EACCDN;
- + if (!b)
- + return EACCDN;
-
- strncpy(b->name, name, BNAME_MAX);
- b->name[BNAME_MAX] = 0;
- b->device = 0;
- b->private = EINVFN;
- b->flags = 0;
- - b->tty = kmalloc((long)strlen(to)+1);
- +
- + b->tty = kmalloc(strlen(to)+1);
- if (!b->tty) {
- kfree(b);
- return EACCDN;
- }
- +
- strcpy((char *)b->tty, to);
- +
- + set_xattr(&b->xattr, S_IFLNK | DEFAULT_DIRMODE);
- + b->xattr.size = strlen(to)+1; /* this must include the \0 */
- +
- b->next = broot;
- broot = b;
- +
- return 0;
- }
-
- static long ARGS_ON_STACK
- @@ -639,10 +715,13 @@
- int buflen;
- {
- struct bios_file *b = (struct bios_file *)fc->index;
-
- - if (!b) return EINVFN;
- - if (b->device) return EINVFN;
- + if (!b)
- + return EINVFN;
- +
- + if (b->device)
- + return EINVFN;
-
- strncpy(buf, (char *)b->tty, buflen);
- if (strlen((char *)b->tty) >= buflen)
- return ENAMETOOLONG;
- @@ -783,18 +862,31 @@
- long ARGS_ON_STACK
- null_write(f, buf, bytes)
- FILEPTR *f; const char *buf; long bytes;
- {
- - UNUSED(f); UNUSED(buf);
- + struct bios_file *b = (struct bios_file *)f->fc.index;
- +
- + UNUSED(buf);
- + if (bytes > 0) {
- + b->xattr.mtime = timestamp;
- + b->xattr.mdate = datestamp;
- + }
- +
- return bytes;
- }
-
- long ARGS_ON_STACK
- null_read(f, buf, bytes)
- FILEPTR *f; char *buf; long bytes;
- {
- - UNUSED(f); UNUSED(buf);
- - UNUSED(bytes);
- + struct bios_file *b = (struct bios_file *)f->fc.index;
- +
- + UNUSED(buf);
- + if (bytes > 0) {
- + b->xattr.atime = timestamp;
- + b->xattr.adate = datestamp;
- + }
- +
- return 0;
- }
-
- long ARGS_ON_STACK
- @@ -891,8 +983,9 @@
- {
- long *r;
- long ret = 0;
- int bdev = f->fc.aux;
- + struct bios_file *b = (struct bios_file *)f->fc.index;
-
- r = (long *)buf;
-
- /* Check for control characters on any newline output.
- @@ -920,8 +1013,13 @@
- }
- #if 0
- (void)checkkeys();
- #endif
- + if (ret > 0) {
- + b->xattr.mtime = timestamp;
- + b->xattr.mdate = datestamp;
- + }
- +
- return ret;
- }
-
- static long ARGS_ON_STACK
- @@ -929,8 +1027,9 @@
- FILEPTR *f; char *buf; long bytes;
- {
- long *r, ret = 0;
- int bdev = f->fc.aux;
- + struct bios_file *b = (struct bios_file *)f->fc.index;
-
- r = (long *)buf;
-
- if ((f->flags & O_NDELAY)) {
- @@ -945,8 +1044,12 @@
- *r++ = bconin(bdev) & 0x7fffffffL;
- bytes -= 4; ret += 4;
- }
- }
- + if (ret > 0) {
- + b->xattr.atime = timestamp;
- + b->xattr.adate = datestamp;
- + }
- return ret;
- }
-
- /*
- @@ -960,8 +1063,9 @@
- {
- long ret = 0;
- int bdev = f->fc.aux;
- int c;
- + struct bios_file *b = (struct bios_file *)f->fc.index;
-
- while (bytes > 0) {
- if ( (f->flags & O_NDELAY) && !bcostat(bdev) )
- break;
- @@ -972,8 +1076,12 @@
- break;
-
- bytes--; ret++;
- }
- + if (ret > 0) {
- + b->xattr.mtime = timestamp;
- + b->xattr.mdate = datestamp;
- + }
- return ret;
- }
-
- static long ARGS_ON_STACK
- @@ -981,15 +1089,20 @@
- FILEPTR *f; char *buf; long bytes;
- {
- long ret = 0;
- int bdev = f->fc.aux;
- + struct bios_file *b = (struct bios_file *)f->fc.index;
-
- while (bytes > 0) {
- if ( (f->flags & O_NDELAY) && !bconstat(bdev) )
- break;
- *buf++ = bconin(bdev) & 0xff;
- bytes--; ret++;
- }
- + if (ret > 0) {
- + b->xattr.atime = timestamp;
- + b->xattr.adate = datestamp;
- + }
- return ret;
- }
-
- /*
- @@ -1422,8 +1535,9 @@
- {
- long count = 0;
- int mhead;
- unsigned char *foo;
- + struct bios_file *b = (struct bios_file *)f->fc.index;
-
- mhead = mousehead;
- foo = &mousebuf[mhead];
-
- @@ -1445,8 +1559,12 @@
- count++;
- --nbytes;
- }
- mousehead = mhead;
- + if (count > 0) {
- + b->xattr.atime = timestamp;
- + b->xattr.adate = datestamp;
- + }
- return count;
- }
-
- static long ARGS_ON_STACK
- diff -u4 orig/fasttext.c my/fasttext.c
- --- orig/fasttext.c Fri Nov 19 15:34:18 1993
- +++ my/fasttext.c Sat Nov 27 18:33:42 1993
- @@ -1221,8 +1221,9 @@
- static long ARGS_ON_STACK
- screen_write(f, buf, bytes)
- FILEPTR *f; const char *buf; long bytes;
- {
- + struct bios_file *b = (struct bios_file *)f->fc.index;
- SCREEN *v = current;
- long *r;
- long ret = 0;
- int c;
- @@ -1244,15 +1245,20 @@
- else
- v->hidecnt = 0;
- curs_on(v);
- v->flags &= ~CURS_UPD;
- + if (ret > 0) {
- + b->xattr.mtime = timestamp;
- + b->xattr.mdate = datestamp;
- + }
- return ret;
- }
-
- static long ARGS_ON_STACK
- screen_read(f, buf, bytes)
- FILEPTR *f; char *buf; long bytes;
- {
- + struct bios_file *b = (struct bios_file *)f->fc.index;
- long *r, ret = 0;
-
- r = (long *)buf;
-
- @@ -1260,8 +1266,12 @@
- if ( (f->flags & O_NDELAY) && !bconstat(CONDEV) )
- break;
- *r++ = bconin(CONDEV) & 0x7fffffffL;
- bytes -= 4; ret += 4;
- + }
- + if (ret > 0) {
- + b->xattr.atime = timestamp;
- + b->xattr.adate = datestamp;
- }
- return ret;
- }
-
- diff -u4 orig/file.h my/file.h
- --- orig/file.h Fri Nov 19 15:34:20 1993
- +++ my/file.h Sat Nov 27 18:32:28 1993
- @@ -550,5 +550,20 @@
- extern struct tty default_tty;
- extern char follow_links[];
- #endif
-
- +/* internal bios file structure */
- +
- +#define BNAME_MAX 13
- +
- +struct bios_file {
- + char name[BNAME_MAX+1]; /* device name */
- + DEVDRV *device; /* device driver for device */
- + short private; /* extra info for device driver */
- + ushort flags; /* flags for device open */
- + struct tty *tty; /* tty structure (if appropriate) */
- + struct bios_file *next;
- + short lockpid; /* owner of the lock */
- + XATTR xattr; /* guess what... */
- +};
- +
- #endif /* _filesys_h */
- diff -u4 orig/mint.h my/mint.h
- --- orig/mint.h Fri Nov 19 15:34:32 1993
- +++ my/mint.h Fri Nov 19 17:01:02 1993
- @@ -228,5 +228,7 @@
- * load some inline functions, perhaps
- */
- #include "inline.h"
-
- +extern int in_dos; /* TeSche: see bios.c & syscall.spp */
- +
- #endif /* GENMAGIC */
- diff -u4 orig/syscall.spp my/syscall.spp
- --- orig/syscall.spp Fri Nov 19 15:34:44 1993
- +++ my/syscall.spp Fri Nov 19 17:35:04 1993
- @@ -66,10 +66,12 @@
- XREF _bconbuf,_bconbsiz,_bconbdev
- XREF _bflush
-
- XREF _ubconstat,_do_bconin,_ubcostat,_kbshift
- -
- + XREF _in_dos
- +
- _mint_dos:
- + move.w #1,_in_dos ; GEMDOS flag
- clr.w -(sp) ; no frame format needed
- ; NOTE: FOR NOW, WE PRESERVE A0 ACROSS GEMDOS CALLS. THIS WILL CHANGE
- ; SOMEDAY, DON'T RELY ON IT!!!
- move.l _curproc,d0 ; note: preserve all regs but d0
- @@ -268,8 +270,9 @@
- addq.w #2,sp ; pop function number off stack
- move.l d0,a0
- jsr (a0) ; go do the call
- out:
- + clr.w _in_dos ; GEMDOS flag
- move.l _curproc,a0
- move.l d0,P_SYSCTXT+C_D0(a0) ; set d0 in the saved context
- move.w P_SYSCTXT+C_SR(a0),d0 ; get saved status register
-
- diff -u4 orig/tosfs.c my/tosfs.c
- --- orig/tosfs.c Fri Nov 19 15:34:48 1993
- +++ my/tosfs.c Wed Nov 24 09:01:06 1993
- @@ -583,8 +583,13 @@
- if (ti->attr & FA_EXEC) {
- xattr->mode |= (S_IXUSR|S_IXGRP|S_IXOTH);
- }
- xattr->attr = ti->attr & 0xff;
- +
- + xattr->mode &= ~S_IROTH;
- + xattr->mode &= ~S_IWOTH;
- + xattr->mode &= ~S_IXOTH;
- +
- return 0;
- }
-
- static long ARGS_ON_STACK
- @@ -608,9 +613,10 @@
- fcookie *dir;
- int uid, gid;
- {
- UNUSED(dir); UNUSED(uid); UNUSED(gid);
- - return EINVFN;
- +/* ts: ignore errors */
- + return 0;
- }
-
- static long ARGS_ON_STACK
- tos_chmode(fc, mode)
-